#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
混合服务器管理器
结合内存缓存和腾讯云API，提供最佳性能和准确性
"""

import time
import logging
from typing import Dict, List, Optional, Set
from dataclasses import dataclass, field
from enum import Enum
from .task_distribution import Server, ServerStatus
from .tencent_hai_api import TencentHAIClient

logger = logging.getLogger(__name__)


class DataSource(Enum):
    """数据源类型"""
    MEMORY = "memory"      # 内存缓存
    TENCENT_API = "tencent_api"  # 腾讯云API
    HYBRID = "hybrid"      # 混合模式


@dataclass
class ServerInfo:
    """服务器信息"""
    instance_id: str
    region: str
    gpu_type: str
    status: str
    public_ip: Optional[str] = None
    created_time: float = field(default_factory=time.time)
    
    # 实时状态（仅内存中有）
    current_tasks: int = 0
    cpu_usage: float = 0.0
    gpu_usage: float = 0.0
    memory_usage: float = 0.0
    last_health_check: float = field(default_factory=time.time)
    
    # 数据源标记
    data_source: DataSource = DataSource.MEMORY
    last_sync_time: float = field(default_factory=time.time)


class HybridServerManager:
    """混合服务器管理器"""
    
    def __init__(self, hai_client: TencentHAIClient):
        self.hai_client = hai_client
        self.memory_servers: Dict[str, ServerInfo] = {}
        self.sync_interval = 30  # 30秒同步一次
        self.last_full_sync = 0
        self.cache_ttl = 10  # 缓存10秒
        
    def get_servers(self, use_cache: bool = True) -> List[ServerInfo]:
        """
        获取服务器列表
        
        Args:
            use_cache: 是否使用缓存
            
        Returns:
            服务器列表
        """
        current_time = time.time()
        
        # 如果缓存有效且允许使用缓存
        if (use_cache and 
            current_time - self.last_full_sync < self.cache_ttl and 
            self.memory_servers):
            logger.debug("使用内存缓存获取服务器列表")
            return list(self.memory_servers.values())
        
        # 从腾讯云API获取最新数据
        logger.debug("从腾讯云API获取服务器列表")
        return self._sync_from_tencent()
    
    def get_server_by_id(self, instance_id: str, use_cache: bool = True) -> Optional[ServerInfo]:
        """
        根据ID获取服务器信息
        
        Args:
            instance_id: 服务器ID
            use_cache: 是否使用缓存
            
        Returns:
            服务器信息
        """
        # 先检查内存缓存
        if use_cache and instance_id in self.memory_servers:
            server = self.memory_servers[instance_id]
            # 如果缓存未过期，直接返回
            if time.time() - server.last_sync_time < self.cache_ttl:
                return server
        
        # 缓存过期或不存在，从腾讯云API获取
        instances = self.hai_client.list_instances()
        for instance in instances:
            if instance.instance_id == instance_id:
                server_info = self._convert_instance_to_server_info(instance)
                # 更新内存缓存
                self.memory_servers[instance_id] = server_info
                return server_info
        
        return None
    
    def update_server_status(self, instance_id: str, **kwargs) -> bool:
        """
        更新服务器状态（仅内存）
        
        Args:
            instance_id: 服务器ID
            **kwargs: 要更新的字段
            
        Returns:
            是否更新成功
        """
        if instance_id not in self.memory_servers:
            return False
        
        server = self.memory_servers[instance_id]
        for key, value in kwargs.items():
            if hasattr(server, key):
                setattr(server, key, value)
        
        server.last_sync_time = time.time()
        logger.debug(f"更新服务器状态: {instance_id} -> {kwargs}")
        return True
    
    def add_server(self, instance_id: str, region: str, gpu_type: str) -> bool:
        """
        添加新服务器到内存缓存
        
        Args:
            instance_id: 服务器ID
            region: 地域
            gpu_type: GPU类型
            
        Returns:
            是否添加成功
        """
        server_info = ServerInfo(
            instance_id=instance_id,
            region=region,
            gpu_type=gpu_type,
            status="CREATING",
            data_source=DataSource.MEMORY
        )
        
        self.memory_servers[instance_id] = server_info
        logger.info(f"添加服务器到内存缓存: {instance_id}")
        return True
    
    def remove_server(self, instance_id: str) -> bool:
        """
        从内存缓存移除服务器
        
        Args:
            instance_id: 服务器ID
            
        Returns:
            是否移除成功
        """
        if instance_id in self.memory_servers:
            del self.memory_servers[instance_id]
            logger.info(f"从内存缓存移除服务器: {instance_id}")
            return True
        return False
    
    def force_sync(self) -> Dict[str, any]:
        """
        强制同步所有服务器
        
        Returns:
            同步结果
        """
        logger.info("强制同步服务器列表...")
        result = self._sync_from_tencent()
        
        return {
            "sync_time": time.time(),
            "total_servers": len(result),
            "memory_servers": len(self.memory_servers),
            "success": True
        }
    
    def _sync_from_tencent(self) -> List[ServerInfo]:
        """
        从腾讯云API同步服务器列表
        
        Returns:
            同步后的服务器列表
        """
        try:
            # 获取腾讯云实例列表
            instances = self.hai_client.list_instances()
            tencent_server_ids = {instance.instance_id for instance in instances}
            memory_server_ids = set(self.memory_servers.keys())
            
            # 计算差异
            added_servers = tencent_server_ids - memory_server_ids
            removed_servers = memory_server_ids - tencent_server_ids
            
            # 添加新服务器
            for instance in instances:
                if instance.instance_id in added_servers:
                    server_info = self._convert_instance_to_server_info(instance)
                    self.memory_servers[instance.instance_id] = server_info
                    logger.info(f"同步添加服务器: {instance.instance_id}")
            
            # 移除不存在的服务器
            for instance_id in removed_servers:
                del self.memory_servers[instance_id]
                logger.info(f"同步移除服务器: {instance_id}")
            
            # 更新现有服务器状态
            for instance in instances:
                if instance.instance_id in memory_server_ids:
                    server_info = self.memory_servers[instance.instance_id]
                    server_info.status = instance.status
                    server_info.public_ip = getattr(instance, 'public_ip', None)
                    server_info.last_sync_time = time.time()
                    server_info.data_source = DataSource.TENCENT_API
            
            self.last_full_sync = time.time()
            logger.info(f"同步完成: 新增{len(added_servers)}, 移除{len(removed_servers)}")
            
            return list(self.memory_servers.values())
            
        except Exception as e:
            logger.error(f"同步失败: {e}")
            return list(self.memory_servers.values())
    
    def _convert_instance_to_server_info(self, instance) -> ServerInfo:
        """
        将腾讯云实例转换为服务器信息
        
        Args:
            instance: 腾讯云实例对象
            
        Returns:
            服务器信息
        """
        return ServerInfo(
            instance_id=instance.instance_id,
            region=instance.region,
            gpu_type=instance.gpu_type,
            status=instance.status,
            public_ip=getattr(instance, 'public_ip', None),
            data_source=DataSource.TENCENT_API,
            last_sync_time=time.time()
        )
    
    def get_statistics(self) -> Dict[str, any]:
        """
        获取服务器统计信息
        
        Returns:
            统计信息
        """
        current_time = time.time()
        servers = list(self.memory_servers.values())
        
        total_servers = len(servers)
        running_servers = len([s for s in servers if s.status == "RUNNING"])
        healthy_servers = len([s for s in servers if s.status == "RUNNING" and 
                              current_time - s.last_health_check < 60])
        
        return {
            "total_servers": total_servers,
            "running_servers": running_servers,
            "healthy_servers": healthy_servers,
            "last_sync_time": self.last_full_sync,
            "cache_age": current_time - self.last_full_sync,
            "memory_cache_size": len(self.memory_servers)
        }
